#! /usr/bin/env python3
import subprocess

# Import Object
from .initialize import initializer
from .report import report


class ExploitDBSearch:
    # Perfom searches in exploit-db
    def __init__(self):
        self.url = None
        self.pluginPath = None
        self.query = None
        self.cmstype = None
        self.headers = initializer.headers
        self.flagged = []
        self.exclude = []
        self.edbpath = initializer.edbpath
        self.edbtype = initializer.edbtype

    # Find EDB-IDs related to vulnerable versions of CMSs in the local exploit-db
    def OfflineCore(self):
        if self.query is not None:
            msg = "Core vulnerabilities for version " + self.query
            report.verbose(msg)
            if self.edbtype.lower() == "git":
                self.searchsploit = self.edbpath+"searchsploit"
            else:
                self.searchsploit = "searchsploit"
            self.grepCMD = self.searchsploit+" --colour " + self.cmstype + " | grep -E \" " + self.query + "|<" + self.query + "|=" + self.query + "|<=" + self.query + "\" | grep -ivE \"plugin|component|extension|module|theme\" | cut -d \"|\" -f 2 | cut -d \".\" -f1 | rev | cut -d \"/\" -f1 | rev | sort -u"
            p = subprocess.Popen(self.grepCMD, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
            output, error = p.communicate()
            ExploitIds = output.splitlines()
            if ExploitIds:
                for Eid in ExploitIds:
                    if Eid not in self.flagged:
                        p = subprocess.Popen("grep -m 1 " + Eid + " " + self.edbpath + "files_exploits.csv | cut -d \",\" -f3",
                            stdout=subprocess.PIPE, shell=True, universal_newlines=True)
                        output, error = p.communicate()
                        msg = " EDB-ID: " + Eid + " " + output.strip()
                        report.medium(msg)
                        self.flagged.append(Eid)
                    self.flagged = sorted(set(self.flagged))

    # Find EDB-IDs related to vulnerable pluglins/modules/components of CMSs in the local exploit-db
    def OfflinePlugins(self):
        if self.query is not None:
            msg = "Searching vulnerable plugins from local ExploitDB repository ..."
            report.verbose(msg)
            for plugin, version in self.query.items():
                if version: 
                    msg = plugin+" v"+version
                else:
                    msg = plugin
                report.info(msg)
                if not initializer.NoExploitdb:
                    if plugin not in self.exclude:
                        p = subprocess.Popen("grep -ilRE " + self.pluginPath + plugin + "[\&=/] " + self.edbpath + 
                            "exploits/php/ | xargs -r grep -ilR " + self.cmstype + 
                            " | cut -d \".\" -f1 | rev | cut -d \"/\" -f1 | rev | sort -u", stdout=subprocess.PIPE, shell=True, universal_newlines=True)
                        output, error = p.communicate()
                        ExploitIds = output.splitlines()
                        if ExploitIds:
                            for Eid in ExploitIds:
                                if Eid not in self.flagged:
                                    p = subprocess.Popen("grep -m 1 " + Eid + " " + self.edbpath + 
                                        "files_exploits.csv | cut -d \",\" -f3", stdout=subprocess.PIPE, shell=True, universal_newlines=True)
                                    output, error = p.communicate()
                                    msg = " EDB-ID: " + Eid + " " + output.strip()
                                    report.medium(msg)
                                    self.flagged.append(Eid)
                                self.flagged = sorted(set(self.flagged))

    # Find EDB-IDs related to vulnerable themes of CMSs in the local exploit-db
    def OfflineTheme(self):
        if self.query is not None:
            theme = self.query
            msg = "Searching vulnerable theme (" + theme + ") from local ExploitDB repository ..."
            report.verbose(msg)
            if not initializer.NoExploitdb:
                if theme not in self.exclude:
                    p = subprocess.Popen("grep -ilR " + theme + " " + self.edbpath + 
                        "exploits/php/webapps/ | xargs -r grep -ilR " + self.cmstype + 
                        "| xargs -r grep -ilE 'theme|template' | cut -d \".\" -f1 | rev | cut -d \"/\" -f1 | rev | sort -u" , 
                        stdout=subprocess.PIPE, shell=True, universal_newlines=True)
                    output , error = p.communicate()
                    ExploitIds = output.splitlines()
                    if ExploitIds:
                        for Eid in ExploitIds:
                            if Eid not in self.flagged:
                                p = subprocess.Popen("grep -m 1 " + Eid + " " + self.edbpath + "files_exploits.csv | cut -d \",\" -f3",
                                    stdout=subprocess.PIPE, shell=True, universal_newlines=True)
                                output, error = p.communicate()
                                msg = " EDB-ID: " + Eid + " " + output.strip()
                                report.medium(msg)
                                self.flagged.append(Eid)
                            self.flagged = sorted(set(self.flagged))


searcher = ExploitDBSearch()
